<template>
  <container-item-wrapper :widget="widget">

    <div :class="['sub-form-container', disabledClass, readModeClass, customClass]"
         v-show="!widget.options.hidden">
      <el-row class="options-row" v-if="!isReadMode && !widget.options.isHideActionBar">
        <el-button v-if="widget.options.morePermissions.handleAdd" @click="addSubFormRow"><el-icon>
            <Plus />
          </el-icon>新建</el-button>
        <el-button v-if="widget.options.morePermissions.handleCopy" @click="copySubFormRow(currentIndex)"><el-icon>
            <DocumentCopy />
          </el-icon>复制</el-button>
        <el-button v-if="widget.options.morePermissions.handleDeleteRow"
          @click="deleteSubFormRow(currentIndex)"><el-icon>
            <Delete />
          </el-icon>删除</el-button>
        <!-- <el-button v-if="widget.options.morePermissions.handleDeleteRow" @click="delAllSubFormRow"><el-icon> -->
        <el-button v-if="widget.options.morePermissions.handleDeleteAll" @click="delAllSubFormRow"><el-icon>
            <Delete />
          </el-icon>删除全部</el-button>
        <el-button v-if="widget.options.morePermissions.handleExport" @click="onclickBatchImport"><el-icon>
            <Upload />
          </el-icon>导入数据</el-button>
        <el-button v-if="widget.options.morePermissions.handleImport" @click="onclickBatchExport"><el-icon>
            <Download />
          </el-icon>导出数据</el-button>
        <el-button v-if="widget.options.isBatchPadding" @click="batchPaddingHandle"><el-icon>
            <Plus />
          </el-icon>批量添加</el-button>
        <el-button v-if="widget.hasDataMapping" @click.stop="openDataMappingDialog($event, widget)">
          <span title="数据对应关系关联">
            <svg-icon :icon-class="widget.mappingIcon" :size="16" color="#2E5CF6" />
          </span>
        </el-button>

        <ZHLXCommonSelect ref="zhlxCommonSelectRef" v-if="widget.options.isBatchPadding" title="批量添加"
          :model-value="selectedAuditor" isReturnData :authorityList="[]" choosePerson="person" :multiple="true"
          :showInput="false" @change="handleSelectedAuditorChange" />
      </el-row>
      <el-row class="header-row" :class='widget.options.isRowWidth100 ? "isRowWidth100" : ""'
        :style="{ 'height': widget.options.labelHeight + 'px', 'font-size': widget.options.fontSize + 'px', 'background': widget.options.labelBackgroundColor + ' !important', 'font-family': widget.options.fontFamily, 'color': widget.options.fontColor, 'font-weight': widget.options.fontBlod ? 'bold' : '' }">
        <!-- <div class="action-header-column">
          <span class="action-label">{{i18nt('render.hint.subFormAction')}}</span>
          <el-button v-if="!isReadMode" :disabled="widgetDisabled || actionDisabled || insertDisabled"
                     round type="primary" size="small" class="action-button"
                     @click="addSubFormRow" :title="i18nt('render.hint.subFormAddActionHint')">
            {{i18nt('render.hint.subFormAddAction')}}<i class="el-icon-plus el-icon-right"></i></el-button>
          <div v-if="!isReadMode && !widget.options.disabled" style="float: right">
            <el-button type="primary" link @click="toggleDeleteButton">
              <el-icon style="margin-right: 4px"><Delete /></el-icon>
              {{i18nt('render.hint.toggleDeleteButton')}}</el-button>
          </div>
        </div> -->
        <div class="row-no-header-column" :style="{ 'background': widget.options.labelBackgroundColor + ' !important' }"
          v-if="widget.options.showNumColumn">
          <span>序号</span>
        </div>
        <template v-for="(subWidget, index) in widget.widgetList" :key="subWidget.id + 'thc'">
          <div v-if="!subWidget.options.hidden" class="field-header-column"
            :class="[getLabelAlign(widget, subWidget), !!subWidget.options.required ? 'is-required' : '', index === widget.widgetList.length - 1 ? '' : 'no-border-right']"
            :style="{ width: subWidget.options.columnWidth, 'background': widget.options.labelBackgroundColor + ' !important' }">
          </div>
        </template>
      </el-row>
      <div v-for="(subFormRowId, sfrIdx) in pagedRowIdData" class="sub-form-row" :key="subFormRowId"
        :class="[currentIndex == getSubFormRowIndex(sfrIdx) ? 'active' : '', widget.options.isRowWidth100 ? 'isRowWidth100' : '']"
        @click="selectRowHandle(getSubFormRowIndex(sfrIdx))">
        <!-- <div v-if="leftActionColumn" class="sub-form-action-column hide-label">
          <div class="action-button-column">
            <el-button :disabled="widgetDisabled || actionDisabled || insertDisabled"
                       circle type="" icon="el-icon-circle-plus-outline" @click="insertSubFormRow(sfrIdx)"
                       v-show="!isReadMode && !widget.options.appendButtonAtBottom"
                       :title="i18nt('render.hint.insertSubFormRow')"></el-button>
            <el-button :disabled="widgetDisabled || actionDisabled || deleteDisabled"
                       circle type="" icon="el-icon-delete" @click="deleteSubFormRow(sfrIdx)"
                       v-show="!isReadMode && !widget.options.deleteButtonHidden"
                       :title="i18nt('render.hint.deleteSubFormRow')"></el-button>
            <span v-if="widget.options.showNumColumn" class="row-number-span">#{{getSubFormRowIndex(sfrIdx)+1}}</span>
          </div>
        </div> -->
        <div class="sub-form-options" v-if="currentIndex == getSubFormRowIndex(sfrIdx) && !isReadMode">
          <el-dropdown placement="bottom-end">
            <el-button class="sub-form-btn"><svg-icon icon-class="el-plus" /></el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-if="widget.options.morePermissions.handleAdd"
                  @click.stop="insertSubFormRow(getSubFormRowIndex(sfrIdx) + 1)">新建一行</el-dropdown-item>
                <el-dropdown-item v-if="widget.options.morePermissions.handleCopy"
                  @click.stop="copySubFormRow(getSubFormRowIndex(sfrIdx))">复制一行</el-dropdown-item>
                <el-dropdown-item v-if="widget.options.morePermissions.handleDeleteAll"
                  @click.stop="deleteSubFormRow(getSubFormRowIndex(sfrIdx))">删除一行</el-dropdown-item>
                <el-dropdown-item v-if="!widget.options.isAutoSort && !widget.options.morePermissions.readonly"
                  @click.stop="moveSubFormRow(getSubFormRowIndex(sfrIdx), -1)"
                  :disabled="getSubFormRowIndex(sfrIdx) == 0">上移一行</el-dropdown-item>
                <el-dropdown-item v-if="!widget.options.isAutoSort && !widget.options.morePermissions.readonly"
                  @click.stop="moveSubFormRow(getSubFormRowIndex(sfrIdx), 1)"
                  :disabled="getSubFormRowIndex(sfrIdx) == rowIdData.length - 1">下移一行</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
        <div v-if="widget.options.showNumColumn" class="row-no-column">
          <span v-if="widget.options.showNumColumn" class="row-number-span">{{getSubFormRowIndex(sfrIdx)+1}}</span>
        </div>
        <div class="grid-sub-form-data-row">
          <template v-for="(subWidget, swIdx) in widget.widgetList" :key="widgetSchemaData[getSubFormRowIndex(sfrIdx)][swIdx].id">
            <component :is="getComponentByContainer(subWidget)" :widget="widgetSchemaData[getSubFormRowIndex(sfrIdx)][swIdx]"
                       :parent-list="widget.widgetList"
                       :index-of-parent-list="swIdx" :parent-widget="widget"
                       :sub-form-row-id="subFormRowId" :sub-form-row-index="getSubFormRowIndex(sfrIdx)" :sub-form-col-index="swIdx">
              <!-- 子表单暂不支持插槽！！！ -->
            </component>
          </template>
        </div>
        <div v-if="rightActionColumn && !isReadMode" class="sub-form-action-column hide-label">
          <div class="action-button-column">
            <el-button :disabled="widgetDisabled || actionDisabled || insertDisabled"
                       circle type="" icon="el-icon-circle-plus-outline" @click="insertSubFormRow(sfrIdx)"
                       v-show="!isReadMode && !widget.options.appendButtonAtBottom"
                       :title="i18nt('render.hint.insertSubFormRow')"></el-button>
            <el-button :disabled="widgetDisabled || actionDisabled || deleteDisabled"
                       circle type="" icon="el-icon-delete" @click="deleteSubFormRow(sfrIdx)"
                       v-show="!isReadMode && !widget.options.deleteButtonHidden"
                       :title="i18nt('render.hint.deleteSubFormRow')"></el-button>
          </div>
        </div>
      </div>
      <el-row v-if="widget.options.appendButtonAtBottom && !isReadMode && !widget.options.disabled" class="footer-row">
        <el-button type="primary" plain class="sub-form-append-button"
                   :disabled="widgetDisabled || actionDisabled || insertDisabled"
                   @click="addSubFormRow" >
          <el-icon style="margin-right: 6px"><CirclePlus /></el-icon>
          {{i18nt('render.hint.subFormAddRow')}}</el-button>
      </el-row>
      <el-row v-if="widget.options.showPagination">
        <el-pagination
            style="margin-top: 8px"
            layout="total, sizes, prev, pager, next"
            size="small"
            :key="paginationKey"
            :background="background"
            :current-page="currentPage || 1"
            :page-sizes="widget.options.pagination.pageSizes"
            :page-size="currentPageSize"
            :total="rowIdData.length"
            @size-change="handlePageSizeChange"
            @current-change="handleCurrentPageChange" />
      </el-row>
    </div>

  </container-item-wrapper>
</template>

<script>
  import emitter from '@/utils/emitter'
  import i18n from "../../../utils/i18n"
  import {deepClone, generateId, traverseFieldWidgetsOfContainer} from "@/utils/util"
  import refMixin from "../../../components/form-render/refMixin"
  import ContainerItemWrapper from './container-item-wrapper'
  import containerItemMixin from "./containerItemMixin";
  import subformMixin from './subformMixin'
  import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
  import {broadcastFormulaRecalculateEvent} from "@/utils/formula-util";
  import {Delete} from "@element-plus/icons-vue";  
  import SvgIcon from '@/components/svg-icon'
  import ZHLXCommonSelect from '@/components/ZHLX-Components/common/commonSelect/index2.vue' // 选人组件

  export default {
    name: "grid-sub-form-item",
    componentName: 'ContainerItem',
    mixins: [emitter, i18n, refMixin, containerItemMixin, subformMixin],
    components: {
      Delete,
      ContainerItemWrapper,
      ...FieldComponents,
      SvgIcon,
      ZHLXCommonSelect
    },
    props: {
      widget: Object,
    },
    provide() {
      return {
        getSubFormFieldFlag: () => true,
        getSubFormName: () => this.widget.options.name,
      }
    },
    inject: ['refList', 'sfRefList', 'globalModel', 'getReadMode'],
    data() {
      return {
        rowIdData: [],
        widgetSchemaData: [],
        actionDisabled: false,
        insertDisabled: false,  //是否禁止新增、插入记录
        deleteDisabled: false,  //是否禁止删除记录
        currentIndex: null, //当前选中行下标

        fieldWidgetList: [],

        pagedRowIdData: [],  //分页后当前所有可见行RowId数组
        currentPage: 1,
        currentPageSize: 10,
        paginationKey: 'pager' + generateId(),
        background: true,
        selectedAuditor: [],
        fieldWidgetList: [],
      }
    },
    computed: {
      isReadMode() {
        return this.getReadMode()
      },

      leftActionColumn() {
        let showFlag = (this.widget.options.actionColumnPosition || 'left') === 'left'
        showFlag = showFlag && (this.widget.options.showNumColumn || !this.widget.options.deleteButtonHidden ||
            !this.widget.options.appendButtonAtBottom)
        return showFlag
      },

      rightActionColumn() {
        let showFlag = (this.widget.options.actionColumnPosition || 'left') !== 'left'
        showFlag = showFlag && (!this.widget.options.deleteButtonHidden || !this.widget.options.appendButtonAtBottom)
        return showFlag
      },

      widgetDisabled() {
        return !!this.widget.options.disabled
      },

      disabledClass() {
        return !!this.widget.options.disabled ? 'sub-form-disabled' : ''
      },

      readModeClass() {
        return !!this.getReadMode() ? 'sub-form-read-mode' : ''
      },

      customClass() {
        return this.widget.options.customClass || ''
      },

    },
    created() {
      this.initRefList()
      this.registerSubFormToRefList()
      
      this.initRowIdData(true)
      if (!this.widget.options.showPagination) {
        this.pagedRowIdData = this.rowIdData
      } else {
        this.currentPage = 1
        this.currentPageSize = this.widget.options.pagination.pageSize
        this.sliceRowIdData()
      }
      
      this.initWidgetSchemaData(true)
      this.initEventHandler()

      this.handleOnCreated()
    },
    mounted() {
      this.extractFieldWidgetList()
      this.handleSubFormFirstRowAdd()  //默认添加首行后，主动触发相关事件！！

      this.handleOnMounted()
    },
    beforeDestroy() {
      this.unregisterFromRefList()
    },
    methods: {
      /******************** 原有代码 start ********************/
      // 如有新增功能代码，须在最下方自定义代码处增加
      extractFieldWidgetList() {
        this.fieldWidgetList.splice(0, this.fieldWidgetList.length)
        let fieldListFn = (fw) => {
          this.fieldWidgetList.push(fw)
        }
        traverseFieldWidgetsOfContainer(this.widget, fieldListFn)
      },

      getLabelAlign(widget, subWidget) {
        return subWidget.options.labelAlign || widget.options.labelAlign
      },

      registerSubFormToRefList() {
        if (this.widget.type === 'grid-sub-form') {
          this.sfRefList[this.widget.options.name] = this
        }
      },

      initRowIdData(initFlag) {
        if (this.widget.type === 'grid-sub-form') {
          this.rowIdData.splice(0, this.rowIdData.length)  //清除数组必须用splice，length=0不会响应式更新！！
          let subFormModel = this.formModel[this.widget.options.name]
          if (!!subFormModel && (subFormModel.length > 0)) {
            subFormModel.forEach(() => {
              this.rowIdData.push('id' + generateId())
            })

            if (!this.widget.options.showPagination) {
              this.pagedRowIdData = this.rowIdData
            } else {
              this.sliceRowIdData()
            }

            if (!!initFlag) {
              //注意：事件触发需延期执行，SumFormDataChange事件处理代码中可能存在尚未创建完成的组件！！
              setTimeout(() => {
                this.handleSubFormRowChange(subFormModel)
              }, 800)
            }
          }
        }
      },

      addToRowIdData() {
        const newRowId = 'id' + generateId()
        this.rowIdData.push(newRowId)
        if (this.widget.options.showPagination) {
          this.pagedRowIdData.push(newRowId)
        }
      },

      insertToRowIdData(rowIndex, pagedRowIndex) {
        const newRowId = 'id' + generateId()
        this.rowIdData.splice(rowIndex, 0, newRowId)
        if (this.widget.options.showPagination) {
          this.pagedRowIdData.splice(pagedRowIndex, 0, newRowId)
        }
      },

      deleteFromRowIdData(rowIndex, pagedRowIndex) {
        this.rowIdData.splice(rowIndex, 1)
        if (this.widget.options.showPagination && (pagedRowIndex !== undefined)) {
          this.pagedRowIdData.splice(pagedRowIndex, 1)
        }
      },

      getRowIdData() {
        return this.rowIdData
      },

      getWidgetRefOfSubForm(widgetName, rowIndex) {
        let realWidgetName = widgetName + '@row' + this.rowIdData[rowIndex]
        return this.getWidgetRef(realWidgetName)
      },

      initWidgetSchemaData(initFlag) {  //初始化widgetSchemaData！！！
        if (this.widget.type !== 'grid-sub-form') {
          return
        }

        let rowLength = this.rowIdData.length || 1  //至少生成一个数组元素！！
        if (!initFlag) {
          rowLength = this.rowIdData.length
        }
        this.widgetSchemaData.splice(0, this.widgetSchemaData.length)  //清除数组必须用splice，length=0不会响应式更新！！
        if (rowLength > 0) {
          for (let i = 0; i < rowLength; i++) {
            let widgetSchemas = []
            this.widget.widgetList.forEach(swItem => {
              widgetSchemas.push( this.cloneSchemaOfWidget(swItem) )
            })
            this.widgetSchemaData.push(widgetSchemas)
          }
        }
      },

      addToWidgetSchemaData(rowIndex) {
        let widgetSchemas = []
        this.widget.widgetList.forEach(swItem => {
          widgetSchemas.push( this.cloneSchemaOfWidget(swItem) )
        })

        if (rowIndex === undefined) {
          this.widgetSchemaData.push(widgetSchemas)
        } else {
          this.widgetSchemaData.splice(rowIndex, 0, widgetSchemas)
        }
      },

      deleteFromWidgetSchemaData(rowIndex) {
        this.widgetSchemaData.splice(rowIndex, 1)
      },

      cloneSchemaOfWidget(widget) {
        let newWidgetSchema = deepClone(widget)
        newWidgetSchema.id = widget.type + generateId()
        newWidgetSchema.oid = widget.id  //重要：保留原始id!!
        return newWidgetSchema
      },

      initEventHandler() {
        if (this.widget.type !== 'grid-sub-form') {
          return
        }

        this.on$('setFormData', (params) => {
          const newFormData = params[0], disableChangeEvent = params[1]
          this.initRowIdData(false)
          if (!this.widget.options.showPagination) {
            this.pagedRowIdData = this.rowIdData
          } else {
            this.currentPage = 1
            this.currentPageSize = this.widget.options.pagination.pageSize
            this.sliceRowIdData()
          }
          
          this.initWidgetSchemaData(false)

          let subFormData = newFormData[this.widget.options.name] || []
          setTimeout(() => {  //延时触发SubFormRowChange事件, 便于更新计算字段！！
            this.handleSubFormRowChange(subFormData)

            //触发计算公式重新计算
            this.recalculateFormula()
          }, 800)
        })
      },

      handleSubFormFirstRowAdd() {
        if (this.widget.type !== 'grid-sub-form') {
          return
        }

        if (!!this.widget.options.showBlankRow && (this.rowIdData.length === 1)) {
          let oldSubFormData = this.formModel[this.widget.options.name] || []

          //确认组件创建成功后触发事件!!
          this.$nextTick(() => {
            this.handleSubFormRowAdd(oldSubFormData, this.rowIdData[0])
            this.handleSubFormRowChange(oldSubFormData)

            if (!!this.widget.options.disabled) {
              this.disableSubForm()
            }
          })
        }
      },

      addSubFormRow() {
        let newSubFormDataRow = {}
        this.fieldWidgetList.forEach(subFormItem => {
          if (!!subFormItem.formItemFlag) {
            let fieldKeyName = subFormItem.options.name
            fieldKeyName = subFormItem.options.keyNameEnabled ? (subFormItem.options.keyName || fieldKeyName) : fieldKeyName
            newSubFormDataRow[fieldKeyName] = subFormItem.options.defaultValue
          }
        })

        let oldSubFormData = this.formModel[this.widget.options.name] || []
        if (!this.widget.options.showPagination) {
          oldSubFormData.push(newSubFormDataRow)
        } else {
          //插入在当前分页的最后位置！！
          //const newRowIndex = this.currentPage * this.currentPageSize - 1
          const newRowIndex = (this.currentPage - 1) * this.currentPageSize +  this.pagedRowIdData.length
          oldSubFormData.splice(newRowIndex, 0, newSubFormDataRow)
        }
        this.addToRowIdData()
        this.addToWidgetSchemaData()

        //确认组件创建成功后触发事件!!
        this.$nextTick(() => {
          this.handleSubFormRowAdd(oldSubFormData, this.rowIdData[oldSubFormData.length - 1])
          this.handleSubFormRowChange(oldSubFormData)
        })
      },

      /**
       * 插入一行
       * @param {*} beforeFormRowIndex 当前操作行
       */
      insertSubFormRow(beforeFormRowIndex) {
        const realSFRowIndex = this.getSubFormRowIndex(beforeFormRowIndex)
        let newSubFormDataRow = {}
        this.fieldWidgetList.forEach(subFormItem => {
          if (!!subFormItem.formItemFlag) {
            let fieldKeyName = subFormItem.options.name
            fieldKeyName = subFormItem.options.keyNameEnabled ? (subFormItem.options.keyName || fieldKeyName) : fieldKeyName
            newSubFormDataRow[fieldKeyName] = subFormItem.options.defaultValue
          }
        })

        let oldSubFormData = this.formModel[this.widget.options.name] || []
        oldSubFormData.splice(realSFRowIndex, 0, newSubFormDataRow)
        this.insertToRowIdData(realSFRowIndex, beforeFormRowIndex)
        this.addToWidgetSchemaData(realSFRowIndex)

        //确认组件创建成功后触发事件!!
        this.$nextTick(() => {
          this.handleSubFormRowInsert(oldSubFormData, this.rowIdData[realSFRowIndex])
          this.handleSubFormRowChange(oldSubFormData)
        })
      },

      deleteSubFormRow(formRowIndex) {
        const realSFRowIndex = this.getSubFormRowIndex(formRowIndex)
        this.$confirm(this.i18nt('render.hint.deleteSubFormRow') + '?', this.i18nt('render.hint.prompt'), {
          confirmButtonText: this.i18nt('render.hint.confirm'),
          cancelButtonText: this.i18nt('render.hint.cancel')
        }).then(() => {
          let oldSubFormData = this.formModel[this.widget.options.name] || []
          let deletedDataRow = deepClone(oldSubFormData[realSFRowIndex])
          oldSubFormData.splice(realSFRowIndex, 1)
          this.deleteFromRowIdData(realSFRowIndex, formRowIndex)
          this.deleteFromWidgetSchemaData(realSFRowIndex)

          //确认组件创建成功后触发事件!!
          this.$nextTick(() => {
            this.handleSubFormRowDelete(oldSubFormData, deletedDataRow, realSFRowIndex)
            this.handleSubFormRowChange(oldSubFormData)

            //触发计算公式重新计算！！
            broadcastFormulaRecalculateEvent(this)
          })
        }).catch(() => {
          //
        })
      },

      /**
       * 删除最后一行（注意：此方法未考虑子表单的分页！！）
       */
      deleteSubFormLastRow() {
        const lastRowIndex = this.rowIdData.length - 1
        let oldSubFormData = this.formModel[this.widget.options.name] || []
        let deletedDataRow = deepClone(oldSubFormData[lastRowIndex])
        oldSubFormData.splice(lastRowIndex, 1)
        this.deleteFromRowIdData(lastRowIndex)
        this.deleteFromWidgetSchemaData(lastRowIndex)

        //确认组件创建成功后触发事件!!
        this.$nextTick(() => {
          this.handleSubFormRowDelete(oldSubFormData, deletedDataRow, lastRowIndex)
          this.handleSubFormRowChange(oldSubFormData)

          //触发计算公式重新计算！！
          broadcastFormulaRecalculateEvent(this)
        })
      },

      handleSubFormRowChange(subFormData) {
        if (!!this.widget.options.onSubFormRowChange) {
          let customFunc = new Function('subFormData', this.widget.options.onSubFormRowChange)
          customFunc.call(this, subFormData)
        }
      },

      handleSubFormRowAdd(subFormData, newRowId) {
        if (!!this.widget.options.onSubFormRowAdd) {
          let customFunc = new Function('subFormData', 'newRowId', this.widget.options.onSubFormRowAdd)
          customFunc.call(this, subFormData, newRowId)
        }
      },

      handleSubFormRowInsert(subFormData, newRowId) {
        if (!!this.widget.options.onSubFormRowInsert) {
          let customFunc = new Function('subFormData', 'newRowId', this.widget.options.onSubFormRowInsert)
          customFunc.call(this, subFormData, newRowId)
        }
      },

      handleSubFormRowDelete(subFormData, deletedDataRow, deletedRowIndex) {
        if (!!this.widget.options.onSubFormRowDelete) {
          let customFunc = new Function('subFormData', 'deletedDataRow', 'deletedRowIndex', this.widget.options.onSubFormRowDelete)
          customFunc.call(this, subFormData, deletedDataRow, deletedRowIndex)
        }
      },

      setDisabled(flag) {
        this.widget.options.disabled = flag
        if (!!flag) {
          this.disableGridSubForm()
        } else {
          this.enableGridSubForm()
        }
      },

      /**
       * 设置单行子表单是否禁止新增、插入记录
       * @param flag
       */
      setInsertDisabled(flag) {
        this.insertDisabled = flag
      },

      /**
       * 设置单行子表单是否禁止删除记录
       * @param flag
       */
      setDeleteDisabled(flag) {
        this.deleteDisabled = flag
      },

      /**
       * 单独给子表单赋值
       * 注意：该方法仅触发组件的onChange事件以及子表单的onFormRowChange事件，不会触发表单的onFormDataChange等其他事件！！
       * @param subFormValues
       */
      setSubFormValues(subFormValues) {
        this.globalModel.formModel[this.widget.options.name] = subFormValues
        this.initRowIdData(false)
        this.initWidgetSchemaData(false)
        if (!this.widget.options.showPagination) {
          this.pagedRowIdData = this.rowIdData
        } else {
          this.currentPage = 1
          this.sliceRowIdData()
        }

        setTimeout(() => {  //延时触发SubFormRowChange事件, 便于更新计算字段！！
          this.handleSubFormRowChange(subFormValues)

          //刷新子表单计算公式重新计算
          if (this.widget.options.showPagination) {
            this.recalculateFormula()
          }
        }, 800)
      },

      /**
       * 单独为子表单某行的字段组件赋值
       * @param fieldName
       * @param fieldValue
       * @param rowIndex
       */
      setSubFormFieldValue(fieldName, fieldValue, rowIndex) {
        const subFormData = this.globalModel.formModel[this.widget.options.name]
        subFormData[rowIndex][fieldName] = fieldValue

        this.handleSubFormRowChange(subFormData)
      },

      /* 强制刷新跟子表单相关的公式重新计算 */
      recalculateFormula() {
        broadcastFormulaRecalculateEvent(this)
      },

      toggleDeleteButton() {
        this.widget.options.deleteButtonHidden = !this.widget.options.deleteButtonHidden
      },

      getSubFormRowIndex(index) {
        if (!this.widget.options.showPagination) {
          return index
        } else {
          return (this.currentPage - 1) * this.currentPageSize + index
        }
      },

      sliceRowIdData() {
        const pageStart = (this.currentPage - 1 ) * this.currentPageSize
        this.pagedRowIdData = this.rowIdData.slice(pageStart, pageStart + this.currentPageSize)
      },

      //校验当前显示的所有子表单内部组件合法性，返回Promise<Boolean>
      validatePagedSubFields() {
        if (this.pagedRowIdData.length <= 0) {
          return new Promise((resolve) => {
            resolve(true)
          })
        }
        
        const subFieldsArray = []
        this.pagedRowIdData.forEach(rowId => {
          const fwHandler = (fw) => {
            const swRef = this.getWidgetRef(fw.options.name + '@row' + rowId)
            if (swRef && swRef.getPropName) {
              subFieldsArray.push(swRef.getPropName())
            }
          }
          traverseFieldWidgetsOfContainer(this.widget, fwHandler, false)
        })

        if (subFieldsArray.length > 0) {
          return this.getFormRef().getNativeForm().validateField(subFieldsArray)
        } else {
          return new Promise((resolve) => {
            resolve(true)
          })
        }
      },

      /* 重新生成分页组件 */
      refreshPagination() {
        this.paginationKey = 'pager' + generateId()
      },
      
      handlePageSizeChange(pageSize) {
        this.validatePagedSubFields().then(pass => {
          if (pass) {
            this.currentPage = 1
            this.widget.options.pagination.pageSize = pageSize
            this.currentPageSize = pageSize
            this.sliceRowIdData()
          } else {
            this.refreshPagination()
            this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
          }
        }).catch(err => {
          this.refreshPagination()
          this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
        })
      },

      handleCurrentPageChange(currentPage) {
        this.validatePagedSubFields().then(pass => {
          if (pass) {
            this.currentPage = currentPage
            this.sliceRowIdData()
          } else {
            this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
          }
        }).catch(err => {
          this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
        })
      },

      
      /******************** 原有代码 end ********************/


      
      /******************** 自定义代码 start ********************/

      /**
       * 点击节点
       * @param {*} sfrIdx 下标
       */
      selectRowHandle(sfrIdx) {
        if (this.isReadMode) { return; }
        this.currentIndex = sfrIdx;
      },

      /**
       * 复制一行到指定位置 默认为下一行
       * @param {*} beforeFormRowIndex 当前操作行
       * @param {*} targetFormRowIndex 目标行
       * @param {*} needValidation 是否校验 默认校验
       */
      copySubFormRow(beforeFormRowIndex, targetFormRowIndex = beforeFormRowIndex + 1, needValidation = true) {
        if (beforeFormRowIndex == null) {
          this.$message.error('请先选择数据行');
          return;
        }
        let oldSubFormData = this.formModel[this.widget.options.name] || [];
        let newSubFormDataRow = deepClone(oldSubFormData[beforeFormRowIndex]);
        oldSubFormData.splice(targetFormRowIndex, 0, newSubFormDataRow);
        this.insertToRowIdData(targetFormRowIndex);
        this.addToWidgetSchemaData(targetFormRowIndex);

        this.$nextTick(() => {
          this.handleSubFormRowInsert(oldSubFormData, this.rowIdData[targetFormRowIndex]);
          this.handleSubFormRowChange(oldSubFormData);
          // 新增行数据校验
          if (needValidation) {
            this.validSubFormRow(targetFormRowIndex)
          }
        })
      },

      /**
       * 移动一行
       * @param {*} beforeFormRowIndex 当前操作行
       * @param {*} direction -1上 1下
       */
      moveSubFormRow(beforeFormRowIndex, direction) {
        const targetFormRowIndex = beforeFormRowIndex + (direction > 0 ? direction + 1 : direction);
        this.copySubFormRow(beforeFormRowIndex, targetFormRowIndex);
        const delIndex = direction > 0 ? beforeFormRowIndex : beforeFormRowIndex - direction;
        this.deleteSubFormRow(delIndex, true);
        this.currentIndex = beforeFormRowIndex + direction;
        this.validSubFormRow(this.currentIndex)
      },

      /**
       * 删除所有行
       */
      async delAllSubFormRow() {
        const res = await this.$confirm('确定要删除所有行?', this.i18nt('render.hint.prompt'), {
          confirmButtonText: this.i18nt('render.hint.confirm'),
          cancelButtonText: this.i18nt('render.hint.cancel')
        }).catch(() => {
          //
        })
        if (res) {
          this.rowIdData.splice(0, this.rowIdData.length);
          this.fieldWidgetList.splice(0, this.fieldWidgetList.length);
          let oldSubFormData = this.formModel[this.widget.options.name] || [];
          oldSubFormData.splice(0, oldSubFormData.length);
          this.$nextTick(() => {
            this.handleSubFormRowDelete(oldSubFormData);
            this.handleSubFormRowChange(oldSubFormData);
            //触发计算公式重新计算！！
            broadcastFormulaRecalculateEvent(this);
            this.currentIndex = null;
          })
        }
      },

      /**
       * 将二维数组导出为CSV文件并下载
       * @param {Array<Array<string>>} data - 要导出的二维数组
       * @param {string} filename - 导出的CSV文件名
       */
      exportToCSV(data, filename) {
        // 转换数组中的每一行数据为CSV格式
        const csvContent = data.map(row =>
          row.map(item => {
            // 处理包含逗号、回车或双引号的内容
            if (item.includes(',') || item.includes('\n') || item.includes('"')) {
              // 将双引号替换为两个双引号，并包裹在双引号内
              item = `"${item.replace(/"/g, '""')}"`;
            }
            return item;
          }).join(',')
        ).join('\n');
        // 确保使用UTF-8 BOM防止中文乱码
        const bom = '\uFEFF';
        const csvData = bom + csvContent;
        // 创建一个Blob对象并指定MIME类型
        const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
        // 创建一个下载链接
        const link = document.createElement('a');
        if (link.download !== undefined) {
          // 设置下载文件名
          link.href = URL.createObjectURL(blob);
          link.download = filename;
          link.style.visibility = 'hidden';

          // 触发下载
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
      },

      exportSubForm() {
        let data = this.formModel[this.widget.id].map((item, i) => {
          const cell = {};
          if (this.widget.options.showNumColumn) cell['index'] = i + 1;
          for (const k in item) {
            const fieldWidget = this.fieldWidgetList.find(field => field.options.name == k)
            if (fieldWidget.options.hidden) {
              continue;
            }
            let defaultValue = deepClone(item[k]);
            cell[fieldWidget.id] = "";
            if (fieldWidget.type === 'select-unit' && this.isJSON(defaultValue)) {
              defaultValue = JSON.parse(defaultValue);
            }
            if (fieldWidget.type !== "serial-number" && (defaultValue === null || defaultValue === "" || defaultValue === undefined || Array.isArray(defaultValue) && !defaultValue.length)) {
              cell[fieldWidget.id] = "";
            } else if (Array.isArray(defaultValue) && defaultValue.length && !fieldWidget.type.includes('-range')) {
              defaultValue.map((value, index) => {
                cell[fieldWidget.id] += this.createNewData(value, fieldWidget.type, fieldWidget.options, defaultValue.length - index - 1);
              })
            } else {
              cell[fieldWidget.id] = this.createNewData(defaultValue, fieldWidget.type, fieldWidget.options);
            }
          }
          return cell
        })
        let column = this.fieldWidgetList.map(item => {
          if (item.options.hidden) {
            return;
          }
          return { 'name': item.id, 'label': item.options.label }
        }).filter(item => !!item)
        if (this.widget.options.showNumColumn) column.unshift({ 'name': 'index', 'label': '序号' })
        this.exportExcel(
          column,
          data,
          '导出 excel',
          'xlsx'
        )
      },

      /**
       * 判断是否是json字符串
       */
      isJSON(str) {
        try {
          JSON.parse(str);
        } catch (e) {
          return false;
        }
        return true;
      },

      /**
       * 创建统一字段对象
       * @param value 组件对应数组
       * @param type 组件类型
       * @param options 组件配置
       * @param step 剩余循环步数
       */
      createNewData(value, type, options, step = 0) {
        let zhlx_gjz_label = value
        if (!(type === 'select' || type === 'radio' || type === 'checkbox')) {
          if (!value || Array.isArray(value) && !value.length || typeof value !== "object") {
            return zhlx_gjz_label.toString();
          }
        }
        if (type === 'file-list') { // 附件列表
          zhlx_gjz_label = value.originalFilename + (step == 0 ? "" : "、");
        } else if (type === 'select-unit') { // 抄送组件
          zhlx_gjz_label = value.name + value.append;
        } else if (type.includes('select-')) { // 选人组件
          zhlx_gjz_label = value.mainName + (step == 0 ? "" : "、");
        } else if (type === 'process-comments') { // 流程意见
          zhlx_gjz_label = value.handleOpinion;
        } else if (type === 'select' || type === 'radio' || type === 'checkbox') { // 下拉/单选框/多选框
          const selectData = options.optionItems.find(select => select.value == value);
          if (!!selectData) {
            zhlx_gjz_label = selectData.label + (step == 0 ? "" : "、");
          }
        } else if (type === 'time-range' || type === 'date-range') { // 时间范围/日期范围
          zhlx_gjz_label = Array.isArray(value) ? value.join('~') : value.toString();
        }
        return zhlx_gjz_label;
      },

      /**
       * 批量添加
       */
      batchPaddingHandle() {
        this.$refs.zhlxCommonSelectRef.openDialog();
      },

      /**
       * 数据对应关系关联
       * @param {*} $event 
       * @param {*} widget 
       */
      openDataMappingDialog($event, widget) {
        console.log('subform open data mapping dialog')
        this.getGlobalDsv().openDataMappingDialog($event, widget)
      },

      async exportExcel(column, data, filename, format) {
        // 创建excel
        const workbook = new ExcelJS.Workbook();
        // 设置信息
        workbook.creator = "Me";
        workbook.title = filename;
        workbook.created = new Date();
        workbook.modified = new Date();
        // 创建工作表
        const worksheet = workbook.addWorksheet(filename);
        // 设置列名
        let columnsName = [];
        column.forEach((item, index) => {
          let maxLength = 0;
          data.map(cell => {
            let columnLength = cell[item.name] ? cell[item.name].toString().length : 10;
            if (columnLength > maxLength ) {
              maxLength = columnLength;
            }
          })
          let obj = {
            header: item.label, key: item.name, width: maxLength < 10 ? 10 : maxLength
          }
          // 设置列名、键和宽度
          columnsName.push(obj);
        })
        worksheet.columns = columnsName;
        // 添加行
        worksheet.addRows(data);
        // 写入文件

        const uint8Array =
          format === "xlsx"
            ? await workbook.xlsx.writeBuffer()
            : await workbook.csv.writeBuffer();

        const blob = new Blob([uint8Array], { type: "application/octet-binary" });
        if (window.navigator.msSaveOrOpenBlob) {
          // msSaveOrOpenBlob方法返回boolean值
          navigator.msSaveBlob(blob, filename + `.${format}`);
          // 本地保存
        } else {
          const link = document.createElement("a"); // a标签下载
          link.href = window.URL.createObjectURL(blob); // href属性指定下载链接
          link.download = filename + `.${format}`; // dowload属性指定文件名
          link.click(); // click()事件触发下载
          window.URL.revokeObjectURL(link.href); // 释放内存
        }
      },

      exportSubFormCsv() {
        let data = this.formModel[this.widget.id].map(item => {
          const arr = []
          for (const k in item) {
            arr.push((item[k] == 0 || item[k]) ? item[k].toString() : '')
          }
          return arr
        })
        const formHeader = this.widget.widgetList.map(item => item.options.label)
        data.unshift(formHeader)
        this.exportToCSV(data, 'output.csv');
      },

      /**
       * 已选审批对象改变后的回调
       * @param {*} ids 
       * @param {*} records 
       */
      handleSelectedAuditorChange(ids, records) {
        const personName = this.widget.widgetList.filter(item => item.type === 'select-person')[0].id;
        const rowIndex = this.rowIdData.length
        records.forEach(async (item, index) => {
          await this.addSubFormRow();
          personName && this.getWidgetRefOfSubForm(personName, rowIndex + index).onUserUpdate([item.mainId], [item])
        })

      },


      /******************** 自定义代码 end ********************/
      
    },
  }
</script>

<style lang="scss">
.rowBtnContent {
  display: grid;

  .el-button {
    width: 120px;
    margin-bottom: 12px;
    margin-left: 0;
  }
}

.isRowWidth100 {
  width: 100% !important;
}
</style>
<style lang="scss" scoped>
  .no-border-right {
    border-right: 0px !important;
  }

  .no-border-top {
    border-top: 0px !important;
  }

  .sub-form-container {
    margin-bottom: 8px;
    text-align: left; //IE浏览器强制居左对齐
    overflow-x: auto; //配合max-content属性，超出自动显示水平滚动条
    padding-left: 40px;
    padding-top: 8px !important;
    padding-bottom: 8px !important;

    .options-row {
      margin-bottom: 8px !important;
      padding: 0 !important;
      flex-wrap: nowrap;
    }

    :deep(.el-row.header-row) {
      padding: 0;
      display: flex;
    }

    :deep(div.sub-form-row) {
      padding: 0;
      display: flex;
      align-items: center;
      // border: 1px solid #e1e2e3;
      border-left: 1px solid #e1e2e3;
      border-bottom: 1px solid #e1e2e3;
      flex-wrap: nowrap;
      position: relative;

      &.active {
        background: #e8f3fd;

        .sub-form-options {
          display: block;
        }
      }

      .sub-form-options {
        display: none;
        position: absolute;
        top: 50%;
        left: 0;
        transform: translate(-100%, -50%);

        .sub-form-btn {
          width: 20px;
        }
      }

      .row-number-span {
        margin-left: 4px;
      }
    }
  }

  div.action-header-column {
    display: inline-block;
    //width: 120px;
    width: 100%;
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    padding: 8px;

    .action-label {
      margin-right: 12px;
    }

    .action-button {
      padding-left: 8px;
      padding-right: 8px;
    }
  }

  div.row-no-header-column {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    text-align: center;
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    border-right: 0px;
    min-height: 36px;
  }

  div.field-header-column {
    display: inline-block;
    //overflow: hidden;
    //white-space: nowrap;  //文字超出长度不自动换行
    //text-overflow: ellipsis;  //文字超出长度显示省略号
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    padding: 8px;
    min-height: 18px;
    flex: 1;

    span.custom-label i {
      margin: 0 3px;
    }
  }

  div.field-header-column.is-required:before {
    content: '*';
    color: #F56C6C;
    margin-right: 4px;
  }

  div.label-center-left {
    text-align: left;
  }

  div.label-center-align {
    text-align: center;
  }

  div.label-right-align {
    text-align: right;
  }

  div.sub-form-action-column {
    display: inline-block;
    align-items: center;
    text-align: center;
    width: 120px;
    padding: 4px 8px;

    :deep(.el-form-item) {
      margin-bottom: 0;
    }

  :deep(.el-button) {
      font-size: 18px;
      padding: 0;
      background: #DCDFE6;
      border: 4px solid #DCDFE6;
    }

  }

  div.grid-sub-form-data-row {
    display: inline-block;
    width: 100%;
    border-left: 1px solid #e1e2e3;
    border-right: 1px solid #e1e2e3;
  }

  div.sub-form-action-column.hide-label {
    :deep(.el-form-item__label) {
      display: none;
    }
  }

  div.row-no-column {
    display: flex;
    align-items: center;
    width: 50px;
    // border-radius: 10px;
    // background: #f1f2f3;
    // padding: 5px 0;
    // margin: 0 6px;
    justify-content: center;
    border-right: 0px;
    border-top: 0px;
    flex-shrink: 0; 
  }

  div.sub-form-table-column {
    display: inline-block;
    border: 1px solid #e1e2e3;
    padding: 8px;

    :deep(.el-form-item) {
      margin-left: 4px;
      margin-right: 4px;
      margin-bottom: 0;
    }

    :deep(.el-form-item__content) {
      margin-left: 0 !important;
    }
  }

  div.sub-form-table-column.hide-label {
    :deep(.el-form-item__label) {
      display: none;
    }
  }

  .footer-row {
    display: block;
    text-align: center;

    .sub-form-append-button {
      margin-top: 8px;
      width: 30%;
    }
  }

</style>
